package cn.jbolt.index;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jfinal.aop.Inject;
import com.jfinal.kit.JsonKit;
import com.jfinal.kit.PropKit;

import cn.jbolt.ApiManager;
import cn.jbolt.common.base.BaseController;
import cn.jbolt.common.base.BaseRepMsg;
import cn.jbolt.common.base.BaseReqMsg;
import cn.jbolt.common.util.AESUtils;
/**
 * IndexController 指向系统访问首页
 * @author jbolt.cn
 * @email 909854136@qq.com
 * @date 2018年11月4日 下午9:02:52
 */
public class IndexController extends BaseController {
	//加密密钥，接口提供方提供给接口调用方使用。
	private final static String SECRET_KEY = PropKit.get("AES_CIPHER_CODE"); 
	@Inject
	private IndexService indexService;
	/**
	 * 首页Action
	 */
	public void index() {
		render("index.html");
	}
	
	/**
	 * 明文数据中不需要包含IV，加密也不一定需要IV，是可选的
	 *解密不需要用到IV，解密时会通过算法获取IV
	 *此处明文中传递IV仅仅演示它可以是动态生成的随机16位字符串
	 *加密解密一定需要用到的是秘钥（SECRET_KEY），此处直接放项目配置文件中，
	 *如果考虑安全，可以放到数据库中，特别是有多个调用方的时候 
	 */
	public void encryptData() {
        JSONObject allParams=getAllParams();
        JSONObject data = allParams.getJSONObject("data");
        String q= AESUtils.encrypt(data.toJSONString(),SECRET_KEY,getPara("iv"),AESUtils.CIPHER_CODE);
        //String sendstr= URLEncoder.encode(q,"UTF-8");
        renderText(q);		
	}
	
	public void parseEncryptedData() {
		JSONObject result = new JSONObject();
		//请求方发过来的数据，拿到后需要做业务处理，这里仅直接返回，展示解密效果
		//这里已经经由DecoderHandler处理，直接获取明文json参数对象
		JSONObject originalData = getAllParams();
		result.put("originalData",originalData);
		//重新对明文json加密，这里没有用到iv，所以每次加密后生成的密文都不一样
		String encryptedData = AESUtils.encrypt(JsonKit.toJson(originalData),SECRET_KEY);
		result.put("encryptedData",encryptedData);
		renderJson(result);
	}
	
	public void parseEncryptedDataByParams(String className,Integer classNo,String[] courses) {
		//测试形参直接获取明文参数
		//对象数组stuList无法直接通过形参获取，应该可以getAllParams()获取
		//通过改进getAllParams()方法，应该也能直接用形参接收对象数组，待实践
		System.out.println("=======形参取值结果=========");
		System.out.println("className:"+className);
		System.out.println("classNo:"+classNo);
		System.out.println("courses:"+JSONObject.toJSONString(courses));
		//获取stuList
		System.out.println("======getAllParams()获取stuList=========");
		JSONObject originalData = getAllParams();
		JSONArray stuList = originalData.getJSONArray("stuList");
		System.out.println(stuList.toJSONString());
		
		//返回值，同parseEncryptedData一致
		JSONObject result = new JSONObject();
		//请求方发过来的数据，拿到后需要做业务处理，这里仅直接返回，展示解密效果
		//这里已经经由DecoderHandler处理，直接获取明文json参数对象
		result.put("originalData",originalData);
		//假设这里要做业务处理，调用相关service方法处理，处理完后，拿到数据
		//---------业务处理，省略-------------------------，这里的值才是真正应该返回的值
		//重新对明文json加密，这里没有用到iv，所以每次加密后生成的密文都不一样
		String encryptedData = AESUtils.encrypt(JsonKit.toJson(originalData),SECRET_KEY);
		result.put("encryptedData",encryptedData);
		renderJson(result);
	}
	
	/**
	 * 测试通过后端ApiManager调用/queryData接口，实际应用中参数的加密处理应该在调用方后台进行
	 * 此处仅演示，调用方请求方代码放在在同一项目中
	 * @param type
	 */
	public void test(Integer type) {
		ApiManager.queryData(type);
		renderText("请查看IDE控制台输出");
	}
	
	/**
	 * 后台ApiManager发起请求访问的接口，模拟实际应用，业务处理逻辑应放在service层
	 * @param type
	 */
	public void queryData() {
		//获取请求参数
		BaseReqMsg reqMsg = getAttr("reqMsg");
		//使用请求参数获取业务数据
		BaseRepMsg repMsg = indexService.queryData(reqMsg);
        //将业务数据进行加密返回
        renderToEncriptedText(repMsg);
        
	}
}